import { apiService } from './api'
import { useTaskStore } from '@/stores/task'
import { useNotificationStore } from '@/stores/notification'

export interface WebSocketMessage {
  type: string
  data?: any
  taskId?: string
  error?: string
}

export class WebSocketService {
  private ws: WebSocket | null = null
  private reconnectAttempts = 0
  private maxReconnectAttempts = 5
  private reconnectDelay = 1000
  private isConnecting = false
  private listeners: Map<string, ((data: any) => void)[]> = new Map()

  constructor() {
    this.connect()
  }

  connect() {
    if (this.isConnecting || (this.ws && this.ws.readyState === WebSocket.CONNECTING)) {
      return
    }

    this.isConnecting = true

    try {
      this.ws = apiService.createWebSocket('/tasks')
      
      this.ws.onopen = () => {
        console.log('WebSocket connected')
        this.isConnecting = false
        this.reconnectAttempts = 0
        this.reconnectDelay = 1000
      }

      this.ws.onmessage = (event) => {
        try {
          const message: WebSocketMessage = JSON.parse(event.data)
          this.handleMessage(message)
        } catch (error) {
          console.error('Failed to parse WebSocket message:', error)
        }
      }

      this.ws.onclose = (event) => {
        console.log('WebSocket disconnected:', event.code, event.reason)
        this.isConnecting = false
        this.ws = null
        
        // 自动重连
        if (this.reconnectAttempts < this.maxReconnectAttempts) {
          setTimeout(() => {
            this.reconnectAttempts++
            this.reconnectDelay *= 2
            this.connect()
          }, this.reconnectDelay)
        }
      }

      this.ws.onerror = (error) => {
        console.error('WebSocket error:', error)
        this.isConnecting = false
      }

    } catch (error) {
      console.error('Failed to create WebSocket connection:', error)
      this.isConnecting = false
    }
  }

  disconnect() {
    if (this.ws) {
      this.ws.close()
      this.ws = null
    }
    this.reconnectAttempts = this.maxReconnectAttempts // 阻止自动重连
  }

  send(message: WebSocketMessage) {
    if (this.ws && this.ws.readyState === WebSocket.OPEN) {
      this.ws.send(JSON.stringify(message))
    } else {
      console.warn('WebSocket is not connected')
    }
  }

  private handleMessage(message: WebSocketMessage) {
    const { type, data, taskId } = message

    // 触发通用监听器
    const listeners = this.listeners.get(type) || []
    listeners.forEach(listener => listener(data))

    // 处理特定消息类型
    switch (type) {
      case 'task_created':
        this.handleTaskCreated(data)
        break
      
      case 'task_progress':
        this.handleTaskProgress(data)
        break
      
      case 'task_completed':
        this.handleTaskCompleted(data)
        break
      
      case 'task_failed':
        this.handleTaskFailed(data)
        break
      
      case 'task_cancelled':
        this.handleTaskCancelled(data)
        break
      
      case 'system_notification':
        this.handleSystemNotification(data)
        break
      
      default:
        console.log('Unknown WebSocket message type:', type)
    }
  }

  private handleTaskCreated(data: any) {
    const taskStore = useTaskStore()
    const notificationStore = useNotificationStore()
    
    taskStore.addTask(data.task)
    notificationStore.notifyTaskStarted(data.task.id, data.task.filename)
  }

  private handleTaskProgress(data: any) {
    const taskStore = useTaskStore()
    
    taskStore.updateTaskProgress(data.taskId, {
      progress: data.progress,
      status: data.status,
      currentStep: data.currentStep
    })
  }

  private handleTaskCompleted(data: any) {
    const taskStore = useTaskStore()
    const notificationStore = useNotificationStore()
    
    taskStore.updateTask(data.taskId, {
      status: 'completed',
      progress: 100,
      completedAt: new Date(data.completedAt),
      outputUrl: data.outputUrl,
      outputSize: data.outputSize
    })
    
    const task = taskStore.getTaskById(data.taskId)
    if (task) {
      notificationStore.notifyTaskCompleted(
        task.id,
        task.filename,
        task.outputFormat
      )
    }
  }

  private handleTaskFailed(data: any) {
    const taskStore = useTaskStore()
    const notificationStore = useNotificationStore()
    
    taskStore.updateTask(data.taskId, {
      status: 'failed',
      error: data.error,
      failedAt: new Date(data.failedAt)
    })
    
    const task = taskStore.getTaskById(data.taskId)
    if (task) {
      notificationStore.notifyTaskFailed(
        task.id,
        task.filename,
        data.error
      )
    }
  }

  private handleTaskCancelled(data: any) {
    const taskStore = useTaskStore()
    
    taskStore.updateTask(data.taskId, {
      status: 'cancelled',
      cancelledAt: new Date(data.cancelledAt)
    })
  }

  private handleSystemNotification(data: any) {
    const notificationStore = useNotificationStore()
    
    switch (data.notificationType) {
      case 'update_available':
        notificationStore.notifySystemUpdate(data.version)
        break
      
      case 'storage_warning':
        notificationStore.notifyStorageWarning(data.usedPercent)
        break
      
      case 'maintenance_mode':
        notificationStore.notifyMaintenanceMode(
          new Date(data.startTime),
          data.duration
        )
        break
      
      default:
        notificationStore.addNotification({
          type: 'system',
          title: data.title || '系统通知',
          message: data.message
        })
    }
  }

  // 监听器管理
  on(type: string, listener: (data: any) => void) {
    if (!this.listeners.has(type)) {
      this.listeners.set(type, [])
    }
    this.listeners.get(type)!.push(listener)
  }

  off(type: string, listener: (data: any) => void) {
    const listeners = this.listeners.get(type)
    if (listeners) {
      const index = listeners.indexOf(listener)
      if (index > -1) {
        listeners.splice(index, 1)
      }
    }
  }

  // 获取连接状态
  get isConnected() {
    return this.ws && this.ws.readyState === WebSocket.OPEN
  }

  get connectionState() {
    if (!this.ws) return 'disconnected'
    
    switch (this.ws.readyState) {
      case WebSocket.CONNECTING:
        return 'connecting'
      case WebSocket.OPEN:
        return 'connected'
      case WebSocket.CLOSING:
        return 'closing'
      case WebSocket.CLOSED:
        return 'disconnected'
      default:
        return 'unknown'
    }
  }
}

// 创建单例实例
export const wsService = new WebSocketService()
export default wsService